package uk.ac.aber.paws.server.remoteinstall;

import java.util.logging.Level;

import uk.ac.aber.paws.server.config.ConfigManager;
import uk.ac.aber.paws.server.core.PAWSInstaller;
import uk.ac.aber.paws.server.db.DBLogger;

/**
 * @author Rob Johnson, Aberystwyth University
 * @email rob.johnson@aber.ac.uk
 * @date 21st May 2012
 * 
 * RemoteInstallOperations.java
 * 
 * Provides functionality for performing remote operations on client computers
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
public class RemoteInstallOperations extends Thread {

	/**
	 * Toggles the client firewall on or off accordingly using the sc command from the server.
	 * @param state True if the firewall is to be turned on, false is to be turned off
	 * @param fqdn The computer name to be actioned
	 */
	public void toggleFirewallService(boolean state, String fqdn) {
		
		String action = "";
		
		if (state) {
			action = "start";
		}
		else {
			action = "stop";
		}
		
		try {
				
			PAWSInstaller.LOG_FILE.log(Level.ALL,"Running command: "+"sc \\\\"+fqdn+" "+action+" mpssvc");
			
			
			// start or stop the service according to state 
			Process p = Runtime.getRuntime().exec("sc \\\\"+fqdn+" "+action+" mpssvc");
			p.waitFor();
		
		}
		catch (InterruptedException ex) {
			System.out.println("Thread stopped");
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * Toggles the PAWS agent service on or off accordingly using the sc command from the server.
	 * @param state True if the PAWS agent is to be turned on, false is to be turned off
	 * @param fqdn The computer name to be actioned
	 */
	public void togglePAWSService(boolean state, String computer) {
		
		String action = "", config = "";
		
		if (state) {
			action = "start";
			config = "auto";
		}
		else {
			action = "stop";
			config = "disabled";
		}
		
		try {
			
			PAWSInstaller.LOG_FILE.log(Level.ALL,"Running command: "+"sc \\\\"+computer+" "+config+" "+ConfigManager.getProperty("app.remoteinstall.source.pawsclientservicename")+" start= "+config);
		
			// either disable or set service to auto depending on state
			Process p = Runtime.getRuntime().exec("sc \\\\"+computer+" config "+ConfigManager.getProperty("app.remoteinstall.source.pawsclientservicename")+" start= "+config);
			p.waitFor();
			
			PAWSInstaller.LOG_FILE.log(Level.ALL,"Running command: "+"sc \\\\"+computer+" "+action+" "+ConfigManager.getProperty("app.remoteinstall.source.pawsclientservicename"));
			
			
			// start or stop the service according to state 
			p = Runtime.getRuntime().exec("sc \\\\"+computer+" "+action+" "+ConfigManager.getProperty("app.remoteinstall.source.pawsclientservicename"));
			p.waitFor();
		
		}
		catch (InterruptedException ex) {
			System.out.println("Thread stopped");
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	/**
	 * Executes a remote batch file on the client computer using xcmd.exe.
	 * @param fqdn The computer name on which the command is to be executed
	 * @param batchFile The batch file on the local client system to be executed
	 * @param flags Any required parameters to be passed to the batch file
	 * @param wait True is the process should wait for the command to complete execution
	 */
	public void executeRemoteBatch(String fqdn, String batchFile, String flags, boolean wait) {
		
		try {
			
			String[] command = {ConfigManager.getProperty("app.main.homedir")+ConfigManager.getProperty("app.main.scriptsdir")+"xcmd.exe ","\\\\"+fqdn,"\""+batchFile+"\"",flags};
			
			PAWSInstaller.LOG_FILE.log(Level.ALL,"Running command: "+ConfigManager.getProperty("app.main.homedir")+ConfigManager.getProperty("app.main.scriptsdir")+"xcmd.exe "+" \\\\"+fqdn+" "+" \""+batchFile+"\" "+flags);
			
			ProcessBuilder pb = new ProcessBuilder(command);
			Process p = pb.start();
			
			if (wait) {
				p.waitFor();
			}
		
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	public void executeRemotePowershell(String fqdn, String powershellFile) {
		
		try {
			
			String[] command = {"powershell.exe",ConfigManager.getProperty("app.psinstall.master"),fqdn,powershellFile};
			
			PAWSInstaller.LOG_FILE.log(Level.ALL,"Running command: "+command[0]+" "+command[1]+" "+command[2]+" "+command[3]);
			
			ProcessBuilder pb = new ProcessBuilder(command);
			Process p = pb.start();
		
			p.getOutputStream().close();
			p.waitFor();
			
			
			
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	/**
	 * Remotely kills any Java processes on the client computer remotely
	 * @param fqdn The computer in which to be interrogated
	 * @param processName The process name in which to be killed
	 */
	public void killProcessses(String fqdn, String processName) {
		
		try {
			
			String[] command = {"cmd.exe", "/c", "taskkill.exe","/s",fqdn,"/IM",processName};
			
			PAWSInstaller.LOG_FILE.log(Level.ALL,"Running command: "+"cmd.exe"+" /c"+" taskkill.exe"+" /s "+fqdn+" /IM "+processName);
			
			ProcessBuilder pb = new ProcessBuilder(command);
			Process p = pb.start();
			p.waitFor();
		
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	/**
	 * Updates the status of the PAWS upgrade/install request within the database
	 * @param id The id of the request
	 * @param status The status to be updated within the database
	 */
	protected void updateRequestStatus(long id, int status) {
		
		(new DBLogger()).updateInstallStatus(id,status);
		
	}
}
